package com.team.admin.auth;

import com.google.common.collect.Sets;
import com.team.admin.domain.SystemUser;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.stereotype.Component;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;
import java.util.Set;

/**
 * 自定义登陆(web后台用)
 */


public class CustomerLoginAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    private final static String CUSTOMER_LOGIN_PATH = "/sys/customer-login";

    private CustomerAuthResponseHandler customerAuthResponseHandler;

    public CustomerLoginAuthenticationFilter(AuthenticationManager authenticationManager,
                                             CustomerAuthResponseHandler customerAuthResponseHandler) {
        super(CUSTOMER_LOGIN_PATH);
        super.setAuthenticationManager(authenticationManager);
        this.customerAuthResponseHandler = customerAuthResponseHandler;
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
                                                HttpServletResponse response)
            throws AuthenticationException, IOException, ServletException {

        String userName = request.getParameter("userName");
        // TODO 密码需要解密
        String password = request.getParameter("password");

        if(StringUtils.isBlank(userName)){
            userName = "";
        }

        if(StringUtils.isBlank(password)){
            password = "";
        }

        UsernamePasswordAuthenticationToken token =
                new UsernamePasswordAuthenticationToken(userName,password);
        setDetails(request, token);
        return getAuthenticationManager().authenticate(token);
    }

    protected void setDetails(HttpServletRequest request,
                              UsernamePasswordAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain chain,
                                            Authentication authResult) throws IOException, ServletException {
        if(authResult != null && !authResult.isAuthenticated()){
            chain.doFilter(request,response);
            return;
        }
        customerAuthResponseHandler.successfulAuthentication(systemUser(authResult),response);
    }

    private SystemUser systemUser(Authentication authResult){

        Set<String> perssions = Sets.newHashSet();
        Collection<? extends GrantedAuthority> grantedAuthorities = authResult.getAuthorities();
        if(CollectionUtils.isNotEmpty(grantedAuthorities)){
            for(GrantedAuthority grantedAuthority : grantedAuthorities){
                perssions.add(grantedAuthority.getAuthority());
            }
        }

        String username = (String)authResult.getPrincipal();

        SystemUser systemUser = new SystemUser();
        systemUser.setUserName(username);
        systemUser.setPermissions(perssions);
        return systemUser;
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request,
                                              HttpServletResponse response,
                                              AuthenticationException failed) throws IOException, ServletException {
        customerAuthResponseHandler.authenticationResult(response,failed);
    }
}
